﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Mahanet.Abyss.PathCalculation
{
	public class Coordinate2DOracleFactory
	{
		#region Fields

		private string m_SelectedFactory;

		#endregion

		#region Public Static Properties

		public static Dictionary<string, Func<IPathOracle<double, Coordinate2D>>> AllFactories { get; private set; }

		#endregion

		#region C'tor

		static Coordinate2DOracleFactory()
		{
			AllFactories = new Dictionary<string, Func<IPathOracle<double, Coordinate2D>>>();
			AllFactories.Add("Least Squares Approximator", CreateLeastSquaresApproximator);
			AllFactories.Add("Ascending Weighted Least Squares Approximator", CreateWeightedLeastSquaresApproximator);
			AllFactories.Add("Gravitic Approximator", CreateGraviticApproximator);
		}

		#endregion

		#region Public Properties

		public string SelectedFactory
		{
			get
			{
				return m_SelectedFactory;
			}
			set
			{
				if (!AllFactories.Keys.Contains(value))
				{
					throw new InvalidOperationException(string.Format("Unknown approximator {0}", value));
				}

				m_SelectedFactory = value;
			}
		}

		#endregion

		#region Public Methods

		public IPathOracle<double, Coordinate2D> Create()
		{
			return AllFactories[SelectedFactory]();
		}

		#endregion

		#region Private Static Methods

		private static IPathOracle<double, Coordinate2D> CreateLeastSquaresApproximator()
		{
			return new LeastSquaresLinearCoordinate2DPathOracle();
		}

		private static IPathOracle<double, Coordinate2D> CreateWeightedLeastSquaresApproximator()
		{
			return new AscendingWeightLeastSquaresLinearCoordinate2DPathOracle();
		}

		private static IPathOracle<double, Coordinate2D> CreateGraviticApproximator()
		{
			return new GraviticLeastSquaresCoordinate2DPathOracle();
		}

		#endregion
	}
}
